package com.example.bluetoothframework.connection

import android.bluetooth.*
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Handler
import android.os.Looper
import android.os.ParcelUuid
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import java.io.IOException
import java.util.*

object ConnectionModule {

    private var bluetoothSocket: BluetoothSocket? = null
    private var gatt: BluetoothGatt? = null
    private var connectedDevice: BluetoothDevice? = null
    private var isBleConnection = false
    private lateinit var appContext: Context // 全局默认 Context

    private val _connectionState = MutableLiveData<ConnectionState>()
    val connectionState: LiveData<ConnectionState> = _connectionState

    private val _pairingState = MutableLiveData<PairingState>()
    val pairingState: LiveData<PairingState> = _pairingState

    private val _systemBluetoothState = MutableLiveData<SystemBluetoothState>()
    val systemBluetoothState: LiveData<SystemBluetoothState> = _systemBluetoothState

    /**
     * 初始化模块，注册系统蓝牙状态和设备状态监听器
     */
    fun initialize(context: Context) {
        // 注册广播监听器
        val filter = IntentFilter().apply {
            addAction(BluetoothAdapter.ACTION_STATE_CHANGED) // 蓝牙状态变化
            addAction(BluetoothDevice.ACTION_ACL_CONNECTED) // 设备连接
            addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED) // 设备断开连接
            addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED) // 配对状态变化
        }

        context.registerReceiver(object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                when (intent.action) {
                    BluetoothAdapter.ACTION_STATE_CHANGED -> handleBluetoothStateChanged(intent)
                    BluetoothDevice.ACTION_BOND_STATE_CHANGED -> handlePairingStateChanged(intent)
                    BluetoothDevice.ACTION_ACL_CONNECTED -> handleDeviceConnected(context, intent)
                    BluetoothDevice.ACTION_ACL_DISCONNECTED -> handleDeviceDisconnected(intent)
                }
            }
        }, filter)

        appContext = context.applicationContext // 保存全局 ApplicationContext

        // 初始化时检测当前已连接的设备
        initializeConnectedDevices(context)
    }

    /**
     * 初始化时检查当前已连接的设备，并在应用中建立连接
     */
    private fun initializeConnectedDevices(context: Context) {
        val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
        val pairedDevices = bluetoothAdapter.bondedDevices

        for (device in pairedDevices) {
            if (isDeviceConnected(device)) {
                // 检测到系统已连接的设备，尝试在应用中建立连接
                connect(context, device, isBle = device.type == BluetoothDevice.DEVICE_TYPE_LE)
            }
        }
    }

    /**
     * 检查设备是否已连接
     */
    private fun isDeviceConnected(device: BluetoothDevice): Boolean {
        return try {
            val method = device.javaClass.getMethod("isConnected")
            method.invoke(device) as Boolean
        } catch (e: Exception) {
            false
        }
    }

    /**
     * 处理蓝牙状态变化
     */
    private fun handleBluetoothStateChanged(intent: Intent) {
        val state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)
        _systemBluetoothState.postValue(
            when (state) {
                BluetoothAdapter.STATE_ON -> SystemBluetoothState.ENABLED
                BluetoothAdapter.STATE_OFF -> SystemBluetoothState.DISABLED
                else -> SystemBluetoothState.UNKNOWN
            }
        )
    }

    /**
     * 处理配对状态变化
     */
    private fun handlePairingStateChanged(intent: Intent) {
        val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
        val bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR)

        if (device != null) {
            _pairingState.postValue(
                when (bondState) {
                    BluetoothDevice.BOND_BONDED -> PairingState.PAIRED
                    BluetoothDevice.BOND_BONDING -> PairingState.PAIRING
                    BluetoothDevice.BOND_NONE -> PairingState.UNPAIRED
                    else -> PairingState.UNKNOWN
                }
            )
        }
    }

    /**
     * 处理设备连接事件
     */
    private fun handleDeviceConnected(context: Context, intent: Intent) {
        val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
        if (device != null && connectedDevice == null) {
            connectedDevice = device
            _connectionState.postValue(ConnectionState.CONNECTED)

            // 避免重复连接
            if (!isConnected()) {
                connect(context, device, isBle = device.type == BluetoothDevice.DEVICE_TYPE_LE)
            }
        }
    }

    /**
     * 处理设备断开连接事件
     */
    private fun handleDeviceDisconnected(intent: Intent) {
        val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
        if (device != null && device == connectedDevice) {
            connectedDevice = null
            _connectionState.postValue(ConnectionState.DISCONNECTED)
        }
    }

    /**
     * 连接设备（支持经典蓝牙和 BLE）
     */
    fun connect(context: Context = appContext, device: BluetoothDevice, isBle: Boolean = false, uuid: UUID? = null) {

        if (isConnected()) disconnect() // 断开现有连接

        if (device.bondState != BluetoothDevice.BOND_BONDED) {
            _pairingState.postValue(PairingState.PAIRING)
            pairDevice(device) { success ->
                if (success) {
                    _pairingState.postValue(PairingState.PAIRED)
                    connectToDevice(context, device, isBle, uuid)
                } else {
                    _pairingState.postValue(PairingState.FAILED)
                }
            }
        } else {
            connectToDevice(context, device, isBle, uuid)
        }
    }

    private fun connectToDevice(context: Context, device: BluetoothDevice, isBle: Boolean, uuid: UUID?) {
        if (isBle) {
            connectBle(context, device)
        } else {
            val supportedUuids = getSupportedUuids(device)

            if (supportedUuids.isNotEmpty()) {
                connectClassic(device, supportedUuids)
            } else {
                // 如果无法获取 UUID 列表，可以尝试使用默认的 RFCOMM UUID
                connectClassic(device, listOf(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")))
            }
        }
    }

    private fun getSupportedUuids(device: BluetoothDevice): List<UUID> {
        return try {
            val method = device.javaClass.getMethod("getUuids")
            val parcelUuids = method.invoke(device) as? Array<ParcelUuid>
            val uuidList = parcelUuids?.map { it.uuid } ?: emptyList()

            // 如果 UUID 列表为空，返回默认 RFCOMM UUID
            if (uuidList.isEmpty()) {
                listOf(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"))
            } else {
                uuidList
            }
        } catch (e: Exception) {
            e.printStackTrace()
            // 返回默认 RFCOMM UUID
            listOf(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"))
        }
    }

    private fun connectClassic(device: BluetoothDevice, uuids: List<UUID>) {
        _connectionState.postValue(ConnectionState.CONNECTING)
        var connectionSuccessful = false

        for (uuid in uuids) {
            try {
                // 尝试使用当前 UUID 进行连接
                bluetoothSocket = device.createRfcommSocketToServiceRecord(uuid)
                bluetoothSocket?.connect()
                connectedDevice = device
                connectionSuccessful = true
                _connectionState.postValue(ConnectionState.CONNECTED)
                break // 连接成功，退出循环
            } catch (e: IOException) {
                e.printStackTrace()
                // 尝试下一个 UUID
            }
        }

        if (!connectionSuccessful) {
            // 如果所有 UUID 都尝试失败，则标记为连接失败
            _connectionState.postValue(ConnectionState.FAILED)
        }
    }


    private fun connectBle(context: Context, device: BluetoothDevice) {
        isBleConnection = true
        _connectionState.postValue(ConnectionState.CONNECTING)
        gatt = device.connectGatt(context, false, object : BluetoothGattCallback() {
            override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
                if (status != BluetoothGatt.GATT_SUCCESS) {
                    // 连接失败时的详细日志和状态更新
                    gatt.close()
                    _connectionState.postValue(ConnectionState.FAILED)
                    return
                }
                if (newState == BluetoothProfile.STATE_CONNECTED) {
                    connectedDevice = device
                    _connectionState.postValue(ConnectionState.CONNECTED)
                    gatt.discoverServices()
                } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                    connectedDevice = null
                    _connectionState.postValue(ConnectionState.DISCONNECTED)
                }
            }
        })
    }

    private fun pairDevice(device: BluetoothDevice, callback: (Boolean) -> Unit) {
        try {
            val createBondMethod = device.javaClass.getMethod("createBond")
            val result = createBondMethod.invoke(device) as Boolean
            if (result) {
                // 超时机制：如果配对未在一段时间内完成，回调失败
                Handler(Looper.getMainLooper()).postDelayed({
                    if (device.bondState != BluetoothDevice.BOND_BONDED) {
                        callback(false)
                    }
                }, 15000) // 超时时间设为 15 秒
            }
        } catch (e: Exception) {
            e.printStackTrace()
            callback(false)
        }
    }


    /**
     * 断开连接
     */
    fun disconnect() {
        bluetoothSocket?.close()
        bluetoothSocket = null

        gatt?.close()
        gatt = null

        connectedDevice = null
        _connectionState.postValue(ConnectionState.DISCONNECTED)
    }

    fun getConnectedDevice(): BluetoothDevice? {
        return connectedDevice
    }

    fun isConnected(): Boolean {
        return _connectionState.value == ConnectionState.CONNECTED
    }
}

/**
 * 连接状态
 */
enum class ConnectionState {
    CONNECTING,
    CONNECTED,
    DISCONNECTED,
    FAILED
}

/**
 * 配对状态
 */
enum class PairingState {
    PAIRING,
    PAIRED,
    UNPAIRED,
    FAILED,
    UNKNOWN
}

/**
 * 系统蓝牙状态
 */
enum class SystemBluetoothState {
    ENABLED,
    DISABLED,
    UNKNOWN
}
